/*
 * Achieve it All! - Android app to motivate achieving your goals
 * Copyright (C) 2014  Xilconic
 * 
 * This file is part of Achieve it All!.
 *
 * Achieve it All! is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Achieve it All! is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Achieve it All!.  If not, see <http://www.gnu.org/licenses/>
 */
package com.xilconic.achieveitall.domain;

import java.util.ArrayList;
import java.util.List;

import android.os.Parcel;
import android.os.Parcelable;

public class Goal implements Parcelable{
	private String name;
	private String description;
	private ArrayList<Target> targets;
	
	public Goal(){
		name = "";
		description = "";
		targets = new ArrayList<Target>();
	}
	
	public Goal(Parcel in) {
		name = in.readString();
		description = in.readString();
		targets = new ArrayList<Target>();
		in.readTypedList(targets, Target.CREATOR);
	}

	/**
	 * Gets the name of this goal.
	 * @return The name.
	 */
	public String getName() {
		return name;
	}

	/**
	 * Set the new name of this goal.
	 * @param newName The new name.
	 */
	public void setName(String newName) {
		name = newName;
	}

	/**
	 * Gets the explanatory text of this goal.
	 * @return The description.
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * Updates the explanatory text of this goal.
	 * @param newDescription The new description.
	 */
	public void setDescription(String newDescription) {
		description = newDescription;
	}

	/**
	 * Gets the collection of {@link Target} objects associated with this goal.
	 * @return This goal's targets.
	 */
	public List<Target> getTargets() {
		return targets;
	}

	/**
	 * Associated a target to this goal.
	 * @param target The newly associated target.
	 */
	public void addTarget(Target target) {
		targets.add(target);
	}

	/**
	 * Removes the given target from this goal.
	 * @param target The target to remove.
	 */
	public void removeTarget(Target target) {
		targets.remove(target);
	}

	/**
	 * Marks a {@link Target} as finished by the user.
	 * @param targetIndex The index of the finished {@link Target}.
	 * @param user The user completing the target.
	 */
	public void finishTarget(int targetIndex, IUser user) {
		if(targetIndex < 0 || targetIndex >= targets.size()){
			String errorMessage = createTargetIndexOutOfRangeMessage(targetIndex);
			throw new IllegalArgumentException(errorMessage);
		}
			
		Target finishedTarget = targets.get(targetIndex);
		finishedTarget.setFinished(true);
		user.scoreAchievementPoints(finishedTarget.getPointsReward());
	}

	private String createTargetIndexOutOfRangeMessage(int targetIndex) {
		StringBuilder builder = new StringBuilder();
		builder.append("targetIndex (");
		builder.append(targetIndex);
		builder.append(") must be in range of the collection targets (size = ");
		builder.append(targets.size());
		builder.append(").");
		String errorMessage = builder.toString();
		return errorMessage;
	}

	@Override
	public int describeContents() {
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeString(name);
		dest.writeString(description);
		dest.writeTypedList(targets);
	}
	
	/**
	 * Object creator to create a {@link Goal} from {@link Parcel}
	 * contents.
	 */
    public static final Parcelable.Creator<Goal> CREATOR
	    = new Parcelable.Creator<Goal>() {
		public Goal createFromParcel(Parcel in) {
		    return new Goal(in);
		}
		
		public Goal[] newArray(int size) {
		    return new Goal[size];
		}
    };

}
